﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DAO
{
    public class DAOCliente
    {
        public static List<Entidad.EntidadCliente> getTodas()
        {
            List<Entidad.EntidadCliente> lista = new List<Entidad.EntidadCliente>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cliente";
                SqlDataReader dr = ad.ejecutarSql(sql, null);

                while (dr.Read())
                {
                    Entidad.EntidadCliente e = new Entidad.EntidadCliente();
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());  
                    e.id_tipo_documento = int.Parse(dr["id_tipo_documento"].ToString());
                    e.id_usuario = int.Parse(dr["id_usuario"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();
                    e.fecha_nacimiento = Convert.ToDateTime(dr["fecha_nacimiento"].ToString());
                    e.id_sexo = int.Parse(dr["id_sexo"].ToString());
                    e.calle = dr["calle"].ToString();
                    e.numero = int.Parse(dr["numero"].ToString());
                    e.id_barrio = int.Parse(dr["id_barrio"].ToString());
                    e.email = dr["email"].ToString();
                    if (dr["telefono"] != DBNull.Value)
                    {
                        e.telefono = Int64.Parse(dr["telefono"].ToString());
                    }
                    if (dr["salario"] != DBNull.Value)
                    {
                        e.salario = float.Parse(dr["salario"].ToString());
                    }

                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los clientes");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }

        public static void Eliminar(Entidad.EntidadCliente cliente)
        {
            String sql = "delete from cliente where id_cliente = @id_cliente";
            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_cliente", cliente.id_cliente));
                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al eliminar el cliente");
            }
        }

        public static void Guardar(Entidad.EntidadCliente cliente)
        {
            String sql = @"insert into cliente (numero_documento,id_tipo_documento,id_usuario,nombre,apellido,fecha_nacimiento,id_sexo,calle,numero,id_barrio,email,telefono,salario)
                                    values(@numero_documento,@id_tipo_documento,@id_usuario,@nombre,@apellido,@fecha_nacimiento,@id_sexo,@calle,@numero,@id_barrio,@email,@telefono,@salario)";
            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();     
                p.Add(new SqlParameter("@numero_documento", cliente.numero_documento));
                p.Add(new SqlParameter("@id_tipo_documento", cliente.id_tipo_documento));
                p.Add(new SqlParameter("@id_usuario", cliente.id_usuario));
                p.Add(new SqlParameter("@nombre", cliente.nombre));
                p.Add(new SqlParameter("@apellido", cliente.apellido));
                p.Add(new SqlParameter("@fecha_nacimiento", cliente.fecha_nacimiento));
                p.Add(new SqlParameter("@id_sexo", cliente.id_sexo));
                p.Add(new SqlParameter("@calle", cliente.calle));
                p.Add(new SqlParameter("@numero", cliente.numero));
                p.Add(new SqlParameter("@id_barrio", cliente.id_barrio));
                p.Add(new SqlParameter("@email", cliente.email));
                if (cliente.telefono.HasValue)
                {
                    p.Add(new SqlParameter("@telefono", cliente.telefono));
                }
                else
                {
                    p.Add(new SqlParameter("@telefono", DBNull.Value));
                }

                if (cliente.salario.HasValue)
                {
                    p.Add(new SqlParameter("@salario", cliente.salario));
                }
                else
                {
                    p.Add(new SqlParameter("@salario", DBNull.Value));
                }
                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al guardar el cliente");
            }
        }

        public static Entidad.EntidadCliente Buscar(int id_cliente)
        {

            Entidad.EntidadCliente e = new Entidad.EntidadCliente();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cliente where id_cliente = @id_cliente";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("id_cliente", id_cliente));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());
                    e.id_tipo_documento = int.Parse(dr["id_tipo_documento"].ToString());
                    e.id_usuario = int.Parse(dr["id_usuario"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();
                    e.fecha_nacimiento = Convert.ToDateTime(dr["fecha_nacimiento"].ToString());
                    e.id_sexo = int.Parse(dr["id_sexo"].ToString());
                    e.calle = dr["calle"].ToString();
                    e.numero = int.Parse(dr["numero"].ToString());
                    e.id_barrio = int.Parse(dr["id_barrio"].ToString());
                    e.email = dr["email"].ToString();
                    if (dr["telefono"] != DBNull.Value)
                    {
                        e.telefono = Int64.Parse(dr["telefono"].ToString());
                    }
                    if (dr["salario"] != DBNull.Value)
                    {
                        e.salario = float.Parse(dr["salario"].ToString());
                    }
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cliente");
            }
            finally
            {
                ad.cerrarDR();
            }

            return e;
        }

        public static Entidad.EntidadClienteQuery BuscarParaVenta(int id_cliente)
        {

            Entidad.EntidadClienteQuery e = new Entidad.EntidadClienteQuery();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select numero_documento, apellido, nombre from cliente where id_cliente = @id_cliente";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_cliente", id_cliente));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cliente");
            }
            finally
            {
                ad.cerrarDR();
            }

            return e;
        }

        public static void Actualizar(Entidad.EntidadCliente cliente)
        {
            String sql = @"update cliente set numero_documento=@numero_documento,
                        id_tipo_documento=@id_tipo_documento,
                        id_usuario=@id_usuario,
                        nombre=@nombre,
                        apellido=@apellido,
                        fecha_nacimiento=@fecha_nacimiento,
                        id_sexo=@id_sexo,
                        calle=@calle,
                        numero=@numero,
                        id_barrio=@id_barrio,
                        email=@email,
                        telefono=@telefono,
                        salario=@salario 
                        where id_cliente = @id_cliente";

            AccesoDato ad = new AccesoDato();
            try
            {
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_cliente", cliente.id_cliente));
                p.Add(new SqlParameter("@numero_documento", cliente.numero_documento));
                p.Add(new SqlParameter("@id_tipo_documento", cliente.id_tipo_documento));
                p.Add(new SqlParameter("@id_usuario", cliente.id_usuario));
                p.Add(new SqlParameter("@nombre", cliente.nombre));
                p.Add(new SqlParameter("@apellido", cliente.apellido));
                p.Add(new SqlParameter("@fecha_nacimiento", cliente.fecha_nacimiento));
                p.Add(new SqlParameter("@id_sexo", cliente.id_sexo));
                p.Add(new SqlParameter("@calle", cliente.calle));
                p.Add(new SqlParameter("@numero", cliente.numero));
                p.Add(new SqlParameter("@id_barrio", cliente.id_barrio));
                p.Add(new SqlParameter("@email", cliente.email));
                if (cliente.telefono.HasValue)
                {
                    p.Add(new SqlParameter("@telefono", cliente.telefono));
                }
                else
                {
                    p.Add(new SqlParameter("@telefono", DBNull.Value));
                }

                if (cliente.salario.HasValue)
                {
                    p.Add(new SqlParameter("@salario", cliente.salario));
                }
                else
                {
                    p.Add(new SqlParameter("@salario", DBNull.Value));
                }

                ad.ejecutarNonQuery(sql, p);
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al actualizar el cliente");
            }
        }
        static public List<Entidad.CDQueryInforme> buscarFiltro(DateTime? fechaDesde, DateTime? fechaHasta, int? id_genero, int? id_sello_discografico)
        {
            List<Entidad.CDQueryInforme> lista = new List<Entidad.CDQueryInforme>();
            List<SqlParameter> p = new List<SqlParameter>();
            AccesoDato ac = null;
            try
            {
                ac = new AccesoDato();
                string sql = @"select cd.id_cd, cd.titulo, sello_discografico.nombre as sello_discografico_nombre, genero.nombre as genero_nombre, sum(detalle_factura.cantidad) as cantidad_vendida, 
                detalle_factura.cantidad * detalle_factura.precio as ganancia
                from cd
                inner join genero on genero.id_genero = cd.id_genero
                inner join sello_discografico on sello_discografico.id_sello_discografico = cd.id_sello_discografico
                inner join detalle_factura on detalle_factura.id_cd = cd.id_cd
                inner join factura on factura.id_factura = detalle_factura.id_factura
                and factura.id_tipo_factura = detalle_factura.id_tipo_factura
                where 1=1";

                if (fechaDesde.HasValue)
                {
                    sql += " and factura.fecha >= @fechaDesde";
                    p.Add(new SqlParameter("@fechaDesde", fechaDesde));
                }
                if (fechaHasta.HasValue)
                {
                    sql += " and factura.fecha <= @fechaHasta";
                    p.Add(new SqlParameter("@fechaHasta", fechaHasta));
                }
                if (id_genero.HasValue)
                {
                    sql += " and cd.id_genero = @id_genero";
                    p.Add(new SqlParameter("@id_genero", id_genero));
                }
                if (id_sello_discografico.HasValue)
                {
                    sql += " and cd.id_sello_discografico = @id_sello_discografico";
                    p.Add(new SqlParameter("@id_sello_discografico", id_sello_discografico));
                }
                sql += " group by cd.id_cd, cd.titulo, sello_discografico.nombre, genero.nombre, detalle_factura.cantidad, detalle_factura.precio";
                SqlDataReader dr = ac.ejecutarSql(sql, p);
                while (dr.Read())
                {
                    Entidad.CDQueryInforme cd = new Entidad.CDQueryInforme();
                    cd.id_cd = int.Parse(dr["id_cd"].ToString());
                    cd.cantidad_vendida = int.Parse(dr["cantidad_vendida"].ToString());
                    cd.ganancia = float.Parse(dr["ganancia"].ToString());
                    cd.titulo = dr["titulo"].ToString();
                    cd.nombre_genero = dr["genero_nombre"].ToString();
                    cd.nombre_sello_discografico = dr["sello_discografico_nombre"].ToString();
                    lista.Add(cd);
                }
            }
            catch (ApplicationException)
            {

                throw new ApplicationException("Error al buscar cds");
            }
            finally
            {
                ac.cerrarDR();
            }
            return lista;
        }

        public static Boolean numeroDocumentoEnUso(long numero_documento)
        {
            Boolean uso = false;
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cliente where numero_documento = @numero_documento";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("numero_documento", numero_documento));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    uso = true;
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cliente.");
            }
            finally
            {
                ad.cerrarDR();
            }

            return uso;
        }

        public static Boolean emailEnUso(string email)
        {
            Boolean uso = false;
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select * from cliente where email = @email";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("email", email));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    uso = true;
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cliente.");
            }
            finally
            {
                ad.cerrarDR();
            }

            return uso;
        }

        public static List<Entidad.EntidadCliente> BuscarPorApellido(string Apellido)
        {
            List<Entidad.EntidadCliente> lista = new List<Entidad.EntidadCliente>();
            AccesoDato ad = new AccesoDato();
           
            try
            {            
                String sql = @"Select * from Cliente where apellido like @Apellido";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@apellido", Apellido + "%"));
                SqlDataReader dr = ad.ejecutarSql(sql, p);
             
                while (dr.Read())
                {                
                    Entidad.EntidadCliente e = new Entidad.EntidadCliente();
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());
                    e.id_tipo_documento = int.Parse(dr["id_tipo_documento"].ToString());
                    e.id_usuario = int.Parse(dr["id_usuario"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();
                    e.fecha_nacimiento = Convert.ToDateTime(dr["fecha_nacimiento"].ToString());
                    e.id_sexo = int.Parse(dr["id_sexo"].ToString());
                    e.calle = dr["calle"].ToString();
                    e.numero = int.Parse(dr["numero"].ToString());
                    e.id_barrio = int.Parse(dr["id_barrio"].ToString());
                    e.email = dr["email"].ToString();
                    if (dr["telefono"] != DBNull.Value)
                    {
                        e.telefono = Int64.Parse(dr["telefono"].ToString());
                    }
                    if (dr["salario"] != DBNull.Value)
                    {
                        e.salario = float.Parse(dr["salario"].ToString());
                    }

                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {            
                throw new ApplicationException("Error al obtener los clientes ");
            }
            finally
            {              
                ad.cerrarDR();
            }
            return lista;

        }

        public static List<Entidad.EntidadCliente> BuscarPorUsuario(int id_usuario)
        {
            List<Entidad.EntidadCliente> lista = new List<Entidad.EntidadCliente>();
            AccesoDato ad = new AccesoDato();

            try
            {
                String sql = @"Select * from Cliente where id_usuario = @id_usuario";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_usuario", id_usuario));
                SqlDataReader dr = ad.ejecutarSql(sql, p);
                

                while (dr.Read())
                {
                    Entidad.EntidadCliente e = new Entidad.EntidadCliente();
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());
                    e.id_tipo_documento = int.Parse(dr["id_tipo_documento"].ToString());
                    e.id_usuario = int.Parse(dr["id_usuario"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();
                    e.fecha_nacimiento = Convert.ToDateTime(dr["fecha_nacimiento"].ToString());
                    e.id_sexo = int.Parse(dr["id_sexo"].ToString());
                    e.calle = dr["calle"].ToString();
                    e.numero = int.Parse(dr["numero"].ToString());
                    e.id_barrio = int.Parse(dr["id_barrio"].ToString());
                    e.email = dr["email"].ToString();
                    if (dr["telefono"] != DBNull.Value)
                    {
                        e.telefono = Int64.Parse(dr["telefono"].ToString());
                    }
                    if (dr["salario"] != DBNull.Value)
                    {
                        e.salario = float.Parse(dr["salario"].ToString());
                    }

                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener los clientes ");
            }
            finally
            {
                ad.cerrarDR();
            }
            return lista;
        }

        public static List<Entidad.EntidadClienteQuery> getTodosGrillaVenta()
        {
            List<Entidad.EntidadClienteQuery> lista = new List<Entidad.EntidadClienteQuery>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = @"Select cliente.id_cliente, tipo_documento.nombre as nombre_tipo_documento, cliente.numero_documento, cliente.apellido, cliente.nombre 
                                from cliente join tipo_documento on cliente.id_tipo_documento = tipo_documento.id_tipo_documento order by cliente.apellido";                           
                SqlDataReader dr = ad.ejecutarSql(sql, null);

                while (dr.Read())
                {
                    Entidad.EntidadClienteQuery e = new Entidad.EntidadClienteQuery();
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.nombre_tipo_documento = dr["nombre_tipo_documento"].ToString();  
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());                              
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();    
   
                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener todos los clientes");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }

        public static List<Entidad.EntidadClienteQuery> BuscarPorUsuarioGrillaVenta(int id_usuario)
        {
            List<Entidad.EntidadClienteQuery> lista = new List<Entidad.EntidadClienteQuery>();
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = @"Select cliente.id_cliente, tipo_documento.nombre as nombre_tipo_documento, cliente.numero_documento, cliente.apellido, cliente.nombre 
                                from cliente join tipo_documento on cliente.id_tipo_documento = tipo_documento.id_tipo_documento 
                                where cliente.id_usuario = @id_usuario";

                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("@id_usuario", id_usuario));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    Entidad.EntidadClienteQuery e = new Entidad.EntidadClienteQuery();
                    e.id_cliente = int.Parse(dr["id_cliente"].ToString());
                    e.nombre_tipo_documento = dr["nombre_tipo_documento"].ToString();
                    e.numero_documento = Int64.Parse(dr["numero_documento"].ToString());
                    e.nombre = dr["nombre"].ToString();
                    e.apellido = dr["apellido"].ToString();

                    lista.Add(e);
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener el cliente");
            }
            finally
            {
                ad.cerrarDR();
            }

            return lista;
        }
    }
}
